package erfgame.frontend.desktop.view.terrain.iso;

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import erfgame.core.Point3D;
import erfgame.core.dao.ObjectDAO;
import erfgame.core.path.BreadthFirstPathCalculator;
import erfgame.core.path.PathCalculator;
import erfgame.core.path.PathElement;
import erfgame.core.world.World;
import erfgame.core.world.terrain.BlockGridTiles;
import erfgame.core.world.terrain.GridTile;
import erfgame.core.world.terrain.TerrainUtils;

public class PathFindingMouseListener extends MouseAdapter {

	private IsometricTerrainView view;
	private PathCalculator calculator;
	private World world;
	private Point3D previousGrid;
	ObjectDAO<Point, BlockGridTiles> gridTilesDAO;
	
	public PathFindingMouseListener( 
			IsometricTerrainView view, 
			World world, 
			PathCalculator calculator, 
			ObjectDAO<Point, BlockGridTiles> gridTilesDAO
	) {
		this.view = view;
		this.world = world;
		this.calculator = calculator;
		this.gridTilesDAO = gridTilesDAO;
	}
	
	public PathFindingMouseListener( IsometricTerrainView view ){
		this.view = view;
	}
	
	@Override
	public void mouseClicked(MouseEvent e) {
		Point3D point = view.getTerrainPosition(e.getX(), e.getY(), new Point3D());
		int tx = point.x;
		int ty = point.y;
		int tz = point.z;
		Point gridCoordinates = world.getGridCoordinates(
				tx, ty
		);
		int gx = gridCoordinates.x;
		int gy = gridCoordinates.y;
		BlockGridTiles blockGridTiles = gridTilesDAO.retrieveObject(
				new Point( 
						gx / world.getXGridTilesPerBlock(), 
						gy / world.getYGridTilesPerBlock()
				)
		);
		GridTile[] gridTiles = blockGridTiles.getGridTiles(
				gx % world.getXGridTilesPerBlock(), 
				gy % world.getYGridTilesPerBlock() 
		);
		int diff = 0;
		int index = -1;
		for( int i=0; i<gridTiles.length; i++ ) {
			int gridTileDiff = Math.abs( gridTiles[i].getZ() - tz );
			if( diff > gridTileDiff || index < 0 ) {
				index = i;
				diff = gridTileDiff;
			}
		}
		view.highlightGrid( gx, gy, index );
		
		if( this.previousGrid != null ) {
			List<PathElement> path = calculator.calculatePath(
					null,
					previousGrid.x, previousGrid.y, previousGrid.z, 
					gx, gy, index, 
					0, 0, world.getBlocksX(), world.getBlocksY()
			);
			view.highlightPath( path );
		}
		
		this.previousGrid = new Point3D( gx, gy, index );
	}
	
}
